package cate.game.role.pvp.throne;

import cate.common.table.activity.throne.TBTrialChallengeRow;
import cate.common.table.activity.throne.TBTrialPointRwdRow;
import cate.common.table.d.GDFight;
import cate.common.table.d.GDFunc;
import cate.common.table.d.GDOperation;
import cate.common.table.d.GDThrone;
import cate.common.util.TimeTool;
import cate.common.util.XT;
import cate.game.play.part.FightSide;
import cate.game.play.part.PlaySide;
import cate.game.play.proce.play.PlayPO;
import cate.game.pvp.throne.TBTrialFTC;
import cate.game.pvp.throne.data.trial.TBTrialReport;
import cate.game.res.MixRes;
import cate.game.res.MixResAdder;
import cate.game.role.Role;
import cate.game.role.farm.AbstractFarm;
import cate.game.role.farm.PlayTimes;
import cate.game.role.pvp.throne.core.TrialOpponent;
import cate.game.role.pvp.throne.msg.RoleTBTrialResp;
import cate.game.role.pvp.throne.msg.TBTrialGetRwdResp;
import cate.game.role.pvp.throne.msg.TBTrialOpponentResp;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;

import java.util.*;

@NoteClass("王座争霸选拔赛")
public class RoleTBTrial extends AbstractFarm {

	@NoteField("积分")
	public int point;

	@NoteField("挑战次数")
	public PlayTimes playTimes;

	@NoteField("奖励领取")
	public Set<Integer> rwdGot;

	@NoteField(value = "战报",detail = "需要单独请求")
	@JsonIgnore
	public List<TBTrialReport> reports;

	@NoteField("上次刷新对手时间")
	public long lastRefreshTime;

	@NoteField(value = "缓存的对手",detail = "不发前端")
    @JsonIgnore
	public  Map<Integer, TrialOpponent> opponents;

	@Override
	public void initialize(Role role) {
		super.initialize(role);
		if (point <= GDThrone.TRIAL_INIT_POINT) {
			point = GDThrone.TRIAL_INIT_POINT;
		}
		if (playTimes == null) {
			playTimes = new PlayTimes();
		}
		playTimes.initialize();
		if (rwdGot == null) {
			rwdGot = new HashSet<>();
		}
		if (reports == null) {
			reports = new ArrayList<>();
		}
		if (opponents == null) {
			opponents = new HashMap<>();
		}
	}

	@Override
	public void onDaySpan(boolean silence) {
		playTimes.reset();
		if(!silence){
			noticeUpdate();
		}
	}

	public void noticeUpdate() {
		role.sendNow(new RoleTBTrialResp(this));
	}

	@Override
	public int getFuncId() {
		return GDFunc.THRONE_TRIAL;
	}

	@Override
	public void onAfterOpen() {

	}

	@Override
	public int getFightFuncId() {
		return GDFunc.THRONE_TRIAL;
	}

	public void onSeasonChange() {
		point = GDThrone.TRIAL_INIT_POINT;
		playTimes.reset();
		rwdGot.clear();
		reports.clear();
		lastRefreshTime = 0L;
		opponents.clear();
	}

	public EcResult<Void> refresh() {
		EcResult<Void> r = new EcResult<>();
		if (!opponents.isEmpty() && lastRefreshTime > 0L && System.currentTimeMillis() - lastRefreshTime < 5 * TimeTool.TimeCons.SECOND) {
			return r.fail("刷新太快了!");
		}
		r = doRefresh();
		if (!r.ok()) {
			return r;
		}
		lastRefreshTime = System.currentTimeMillis();
		role.sendNow(new TBTrialOpponentResp(lastRefreshTime, opponents));
		return r.success();
	}

	public EcResult<Void> doRefresh() {
		EcResult<Void> r = new EcResult<>();
		if(!role.getPvp().throne.picked){
			return r.fail("没有参赛资格");
		}
		if (!role.getGame().pvp.throne.data.holder.base.timeTable.inTrial()) {
			return r.fail("选拔赛已结束");
		}
		opponents = role.getGame().pvp.throne.message.getTrialOpponent(role).opponents;
		TBTrialChallengeRow row = role.getGame().table.throne.challenge.findRow(point);
		//补全机器人
		for (Integer level : GDThrone.TrialLevel.ALL) {
			if (!opponents.containsKey(level)) {
				TBTrialChallengeRow.Range range = row.getRobotRange(level);
				if (range != null) {
					String insCode = role.getGame().table.throne.robot.random();
					int heroDynLevel = XT.randomRange((int) range.start, (int) range.end);
					EcResult<PlaySide> ps_r = role.getGame().fight.side.createPlaySideByCode(insCode, heroDynLevel);
					if (ps_r.ok()) {
						opponents.put(level, new TrialOpponent(level, ps_r.data));
					}
				}
			}
		}
		return r.success();
	}

	public EcResult<Void> challenge(int level) {
		EcResult<Void> r = new EcResult<>();
		if (!role.getGame().pvp.throne.data.holder.base.timeTable.inTrial()) {
			return r.fail("选拔赛已结束");
		}
		if (isFighting()) {
			return r.fail("当前正在战斗中");
		}
		if (!playTimes.available(role, getFuncId()).ok()) {
			return r.fail("挑战次数不足");
		}
		PlaySide psB = opponents.get(level).playSide;
		if (psB == null) {
			return r.fail("选择对手有误");
		}
		TBTrialChallengeRow row = role.getGame().table.throne.challenge.findRow(point);
		if (row == null) {
			return r.fail("挑战配置不存在");
		}
		FightSide sideB = role.getGame().fight.side.createFightSideByPlaySide(GDFight.Team.B, psB);
		TBTrialFTC ftc = new TBTrialFTC(role, level, row);
		ftc.setPositionApply(GDFunc.GRADE_PVP);
		EcResult<PlayPO> r_fp = role.getGame().play.startByRole(role, ftc, sideB);
		if (!r_fp.ok()) {
			return r.fail(r_fp.message);
		}
		playTimes.added();
		noticeUpdate();
		return r.success();
	}

	public EcResult<Void> getPointRwd(int tid) {
		EcResult<Void> r = new EcResult<>();
		if (rwdGot.contains(tid)) {
			return r.fail("奖励已领取");
		}
		TBTrialPointRwdRow rwdRow = role.getGame().table.throne.trialPointRwd.get(tid);
		if (rwdRow == null) {
			return r.fail("奖励不存在");
		}
		if (rwdRow.group != role.getPvp().throne.levelGroup) {
			return r.fail("选择奖励有误");
		}
		if (point < rwdRow.point) {
			return r.fail("积分不足");
		}
		rwdGot.add(tid);
		new MixResAdder().setRes(new MixRes(rwdRow.rwdStr)).
				setOperation(GDOperation.THRONE_TRIAL_POINT).
				setOperationSub(tid).setDialogReward(true).
				exe(role);
		new TBTrialGetRwdResp(rwdGot).sendNow(role);
		return r.success();
	}

	public void addReport(TBTrialReport report) {
		if (this.reports.size() >= 20) {
			this.reports.remove(0);
		}
		this.reports.add(report);
	}
}
